package com.obst.tracenote.util;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import org.json.JSONObject;

import com.obst.tracenote.C;


import android.app.Activity;
import android.util.Log;

public class MyServer {
	private String mUid;
	private Activity targetActivity;
	private int mMethod;
	private static final int METHOD_GET_TRACE		= 0;
	private static final int METHOD_GET_TRACE_LIST	= 1;
	private static final int METHOD_ADD_USER		= 2;
	private static final int METHOD_PUT_TRACE		= 3; 
	/**
	 * @param activity
	 */
	public MyServer(Activity activity, int method) {
		targetActivity = activity;
		mUid = MyPreferences.getAppPreferences(targetActivity, "USER_KEY");
		mMethod	= method;
	}
	
	/**
	 * @param url
	 * @param param
	 * @return string from server
	 */
	private String sendHttp(String url, String param) {
		try {
			URLConnection conn = new URL(url).openConnection();
			conn.setDoOutput(true);
			OutputStreamWriter wr = new OutputStreamWriter(
					conn.getOutputStream());
			if (param != null) {
				wr.write(param);
			}
			wr.flush();
			BufferedReader rd = new BufferedReader(new InputStreamReader(
					conn.getInputStream()));
			String tmpData = "";
			String ldataFromRd = "";
			while ((tmpData = rd.readLine()) != null) {
				ldataFromRd += tmpData;
			}

			Log.v(C.LOG_TAG, "dataFrom : " + url + " = " + ldataFromRd);
			wr.close();
			rd.close();
			return ldataFromRd;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public JSONObject getJSON() {
		switch(this.mMethod) {
		//case METHOD_ADD_USER : this.addUser(uno, uname, authKey);
		}
		return new JSONObject();
	}
	/**
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public JSONObject getMyTraceList() {
		JSONObject rtn = null;
		try {
			if (mUid != null) {
				String lData = URLEncoder.encode("uid", "UTF-8") + "="
						+ URLEncoder.encode(mUid, "UTF-8");
				String lrtn = this.sendHttp(C.URL_MY_TRACE_LIST, lData);
				rtn = new JSONObject(lrtn);
			} else {
				rtn = null;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rtn;
	}
	
	
	/**
	 * @param tid
	 *            (흔적 아이디)
	 * @return JSONObject 흔적에 대한 상세 정보
	 */
	public JSONObject getTrace(String tid) {
		JSONObject rtn = null;
		try {
			String data = URLEncoder.encode("tid", "UTF-8") + "="
					+ URLEncoder.encode(tid, "UTF-8");
			String lRtn = this.sendHttp(C.URL_MY_TRACE, data);
			rtn = new JSONObject(lRtn);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rtn;
	}


	/**
	 * @param tid
	 * @param lati
	 * @param longi
	 * @param ele
	 * @return boolean 보물이 적상적으로 숨겨 졌는지 여부
	 */
	public boolean hideTrace(String tid, double lati, double longi,
			double ele, String title, String addr) {
		try {
			String data = URLEncoder.encode("tid", "UTF-8") + "="
					+ URLEncoder.encode(tid, "UTF-8");
			data += "&" + URLEncoder.encode("uid", "UTF-8") + "="
					+ URLEncoder.encode(mUid, "UTF-8");
			data += "&" + URLEncoder.encode("lati", "UTF-8") + "="
					+ URLEncoder.encode(Double.toString(lati), "UTF-8");
			data += "&" + URLEncoder.encode("longi", "UTF-8") + "="
					+ URLEncoder.encode(Double.toString(longi), "UTF-8");
			data += "&" + URLEncoder.encode("ele", "UTF-8") + "="
					+ URLEncoder.encode(Double.toString(ele), "UTF-8");
			data += "&" + URLEncoder.encode("title", "UTF-8") + "="
			+ URLEncoder.encode(title, "UTF-8");			
			data += "&" + URLEncoder.encode("address", "UTF-8") + "="
					+ URLEncoder.encode(addr, "UTF-8");
			// Send data
			String rtn = this.sendHttp(C.URL_HIDE_TRACE, data);
			if(rtn.equalsIgnoreCase("1")) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * @param tid
	 * @param lati
	 * @param longi
	 * @param ele
	 * @return boolean 보물이 적상적으로 숨겨 졌는지 여부
	 */
	public JSONObject getUserHidedTrace() {
		JSONObject rtn = null;
		try {
			String data = URLEncoder.encode("uid", "UTF-8") + "="
					+ URLEncoder.encode(mUid);
			// Send data
			String lrtn = this.sendHttp(C.URL_HIDED_TRACE_FROM_USER, data);
			rtn = new JSONObject(lrtn);
		} catch (Exception e) {
			// Toast.makeText(targetActivity, "IOException" + e.toString(),
			// Toast.LENGTH_SHORT).show();
			e.printStackTrace();
		}
		return rtn;
	}
	
	
	
	
	
	
	
	
	
	
	
	/**
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public JSONObject getTreasureList() {
		JSONObject rtn = null;
		try {
			if (mUid != null) {
				String lData = URLEncoder.encode("uid", "UTF-8") + "="
						+ URLEncoder.encode(mUid, "UTF-8");
				String lrtn = this.sendHttp(C.URL_TREASURE_LIST, lData);
				rtn = new JSONObject(lrtn);
			} else {
				rtn = null;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rtn;
	}

	/**
	 * @param tid
	 * @param lati
	 * @param longi
	 * @param ele
	 * @return boolean 보물이 적상적으로 숨겨 졌는지 여부
	 */
	public boolean hideTreasure(String tid, double lati, double longi,
			double ele) {
		try {
			ReverseGeocoder rg = new ReverseGeocoder();
			String addr = "알수없는 곳";
			addr = rg.point2address(lati, longi, targetActivity);
			String data = URLEncoder.encode("tid", "UTF-8") + "="
					+ URLEncoder.encode(tid, "UTF-8");
			data += "&" + URLEncoder.encode("mid", "UTF-8") + "="
					+ URLEncoder.encode(mUid, "UTF-8");
			data += "&" + URLEncoder.encode("lati", "UTF-8") + "="
					+ URLEncoder.encode(Double.toString(lati), "UTF-8");
			data += "&" + URLEncoder.encode("longi", "UTF-8") + "="
					+ URLEncoder.encode(Double.toString(longi), "UTF-8");
			data += "&" + URLEncoder.encode("ele", "UTF-8") + "="
					+ URLEncoder.encode(Double.toString(ele), "UTF-8");
			data += "&" + URLEncoder.encode("address", "UTF-8") + "="
					+ URLEncoder.encode(addr, "UTF-8");
			// Send data
			this.sendHttp(C.URL_HIDE_TREASURE, data);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * @param tid
	 *            (흔적 아이디)
	 * @return JSONObject 흔적에 대한 상세 정보
	 */
	public JSONObject getDetailTreasure(String tid) {
		JSONObject rtn = null;
		try {
			String data = URLEncoder.encode("tid", "UTF-8") + "="
					+ URLEncoder.encode(tid, "UTF-8");
			String lRtn = this.sendHttp(C.URL_DETAIL_TREASURE, data);
			rtn = new JSONObject(lRtn);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rtn;
	}

	public JSONObject getMyTreasure() {
		JSONObject rtn = null;
		try {
			String data = URLEncoder.encode("uid", "UTF-8") + "="
					+ URLEncoder.encode(mUid, "UTF-8");
			String lRtn = this.sendHttp(C.URL_MY_TRACE_LIST, data);
			rtn = new JSONObject(lRtn);
		} catch (Exception e) {
			// Toast.makeText(targetActivity, "IOException" + e.toString(),
			// Toast.LENGTH_SHORT).show();
		}
		return rtn;
	}

	/**
	 * @param mTitle
	 * @param mContents
	 * @return
	 */
	public int addTreasure(String mTitle, String mContents) {
		try {
			String data = URLEncoder.encode("content", "UTF-8") + "="
					+ URLEncoder.encode(mContents, "UTF-8");
			data += "&" + URLEncoder.encode("title", "UTF-8") + "="
					+ URLEncoder.encode(mTitle, "UTF-8");
			data += "&" + URLEncoder.encode("uid", "UTF-8") + "="
					+ URLEncoder.encode(mUid, "UTF-8");
			String lRtn = this.sendHttp(C.URL_TREASURE_INSERT, data);
			if (Integer.parseInt(lRtn) > 0) {
				return Integer.parseInt(lRtn); // /<숨긴 흔적의 tid
			} else {
				return 0;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}


	/**
	 * @param uno : facebook user no
	 * @param uname
	 * @param authKey
	 * @return String 성공 : 2, 실패 : 0
	 */
	public String addUser(String uno, String uname, String authKey) {
		String lRtn = "0";
		try {
			String data = URLEncoder.encode("fbauthkey", "UTF-8") + "="
					+ URLEncoder.encode(authKey, "UTF-8");
			data += "&" + URLEncoder.encode("uno", "UTF-8") + "="
					+ URLEncoder.encode(uno, "UTF-8");
			data += "&" + URLEncoder.encode("username", "UTF-8") + "="
					+ URLEncoder.encode(uname, "UTF-8");
			lRtn = this.sendHttp(C.URL_USER_INSERT, data); ///< return userid : success, 0 : fail
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return lRtn;
	}

	/**
	 * @param path
	 * @return
	 */
	public boolean uploadFile(String path) {
		Log.d("Test", "file path = " + path);
		try {
			fileUpload(C.URL_FILE_UPLOAD, "", path);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * @param urlString
	 * @param params
	 * @param fileName
	 */
	private void fileUpload(String urlString, String params, String fileName) {
		try {

			FileInputStream mFileInputStream = new FileInputStream(fileName);
			URL connectUrl = new URL(urlString);
			Log.d("Test", "mFileInputStream  is " + mFileInputStream);
			String boundary = "*****";
			String lineEnd = "\r\n";
			String twoHyphens = "--";
			// open connection
			HttpURLConnection conn = (HttpURLConnection) connectUrl
					.openConnection();
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("Content-Type",
					"multipart/form-data;boundary=" + boundary);

			// write data
			DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
			dos.writeBytes(twoHyphens + boundary + lineEnd);
			dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\""
					+ fileName + "\"" + lineEnd);
			dos.writeBytes(lineEnd);

			int bytesAvailable = mFileInputStream.available();
			int maxBufferSize = 1024;
			int bufferSize = Math.min(bytesAvailable, maxBufferSize);

			byte[] buffer = new byte[bufferSize];
			int bytesRead = mFileInputStream.read(buffer, 0, bufferSize);

			Log.d("Test", "image byte is " + bytesRead);

			// read image
			while (bytesRead > 0) {
				dos.write(buffer, 0, bufferSize);
				bytesAvailable = mFileInputStream.available();
				bufferSize = Math.min(bytesAvailable, maxBufferSize);
				bytesRead = mFileInputStream.read(buffer, 0, bufferSize);
			}

			dos.writeBytes(lineEnd);
			dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

			// close streams
			Log.e("Test", "File is written");
			mFileInputStream.close();
			dos.flush(); // finish upload...
			Log.e("Test", "finish upload");
			dos.close();

		} catch (Exception e) {
			Log.d("Test", "exception " + e.getMessage());
			// TODO: handle exception
		}
	}
}
